﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
using SgAotoArchiveSp;
using Aspose;
using System.Data;
using System.Data.OleDb;
using Aspose.Cells;
using System.Data.SQLite;
using System.Data.SQLite.Linq;
using System.Data.SqlClient;
using SgAutoArchiveBrrDal;

namespace SgAutoArchiveSp
{
    public class SGZip
    {
        /// <summary>
        /// 缓存字节数
        /// </summary>
        private const int BufferSize = 4096;

        /// <summary>
        /// 压缩最小等级
        /// </summary>
        public const int CompressionLevelMin = 0;

        /// <summary>
        /// 压缩最大等级
        /// </summary>
        public const int CompressionLevelMax = 9;

        public static string oldstr;

        /// <summary>
        /// 获取所有文件系统对象
        /// </summary>
        /// <param name="source">源路径</param>
        /// <param name="topDirectory">顶级文件夹</param>
        /// <returns>字典中Key为完整路径，Value为文件(夹)名称</returns>
        private static Dictionary<string, string> GetAllFileSystemEntities(string source, string topDirectory)
        {
            Dictionary<string, string> entitiesDictionary = new Dictionary<string, string>();
            entitiesDictionary.Add(source, source.Replace(topDirectory, ""));

            if (Directory.Exists(source))
            {
                //一次性获取下级所有目录，避免递归
                string[] directories = Directory.GetDirectories(source, "*.*", SearchOption.AllDirectories);
                foreach (string directory in directories)
                {
                    entitiesDictionary.Add(directory, directory.Replace(topDirectory, ""));
                }

                string[] files = Directory.GetFiles(source, "*.*", SearchOption.AllDirectories);
                foreach (string file in files)
                {
                    entitiesDictionary.Add(file, file.Replace(topDirectory, ""));
                }
            }

            return entitiesDictionary;
        }

        /// <summary>
        /// 校验压缩等级
        /// </summary>
        /// <param name="compressionLevel"></param>
        /// <returns></returns>
        private static int CheckCompressionLevel(int compressionLevel)
        {
            compressionLevel = compressionLevel < CompressionLevelMin ? CompressionLevelMin : compressionLevel;
            compressionLevel = compressionLevel > CompressionLevelMax ? CompressionLevelMax : compressionLevel;
            return compressionLevel;
        }

        #region 字节压缩与解压

        /// <summary>
        /// 压缩字节数组
        /// </summary>
        /// <param name="sourceBytes">源字节数组</param>
        /// <param name="compressionLevel">压缩等级</param>
        /// <param name="password">密码</param>
        /// <returns>压缩后的字节数组</returns>
        public static byte[] CompressBytes(byte[] sourceBytes, string password = null, int compressionLevel = 6)
        {
            byte[] result = new byte[] { };

            if (sourceBytes.Length > 0)
            {
                try
                {
                    using (MemoryStream tempStream = new MemoryStream())
                    {
                        using (MemoryStream readStream = new MemoryStream(sourceBytes))
                        {
                            using (ZipOutputStream zipStream = new ZipOutputStream(tempStream))
                            {
                                zipStream.Password = password;//设置密码
                                zipStream.SetLevel(CheckCompressionLevel(compressionLevel));//设置压缩等级

                                ZipEntry zipEntry = new ZipEntry("ZipBytes");
                                zipEntry.DateTime = DateTime.Now;
                                zipEntry.Size = sourceBytes.Length;
                                zipStream.PutNextEntry(zipEntry);
                                int readLength = 0;
                                byte[] buffer = new byte[BufferSize];

                                do
                                {
                                    readLength = readStream.Read(buffer, 0, BufferSize);
                                    zipStream.Write(buffer, 0, readLength);
                                } while (readLength == BufferSize);

                                readStream.Close();
                                zipStream.Flush();
                                zipStream.Finish();
                                result = tempStream.ToArray();
                                zipStream.Close();
                            }
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    throw new Exception("压缩字节数组发生错误", ex);
                }
            }

            return result;
        }

        /// <summary>
        /// 解压字节数组
        /// </summary>
        /// <param name="sourceBytes">源字节数组</param>
        /// <param name="password">密码</param>
        /// <returns>解压后的字节数组</returns>
        public static byte[] DecompressBytes(byte[] sourceBytes, string password = null)
        {
            byte[] result = new byte[] { };

            if (sourceBytes.Length > 0)
            {
                try
                {
                    using (MemoryStream tempStream = new MemoryStream(sourceBytes))
                    {
                        using (MemoryStream writeStream = new MemoryStream())
                        {
                            using (ZipInputStream zipStream = new ZipInputStream(tempStream))
                            {
                                zipStream.Password = password;
                                ZipEntry zipEntry = zipStream.GetNextEntry();

                                if (zipEntry != null)
                                {
                                    byte[] buffer = new byte[BufferSize];
                                    int readLength = 0;

                                    do
                                    {
                                        readLength = zipStream.Read(buffer, 0, BufferSize);
                                        writeStream.Write(buffer, 0, readLength);
                                    } while (readLength == BufferSize);

                                    writeStream.Flush();
                                    result = writeStream.ToArray();
                                    writeStream.Close();
                                }
                                zipStream.Close();
                            }
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    throw new Exception("解压字节数组发生错误", ex);
                }
            }
            return result;
        }

        #endregion

        #region 文件压缩与解压

        /// <summary>
        /// 为压缩准备文件系统对象
        /// </summary>
        /// <param name="sourceFileEntityPathList"></param>
        /// <returns></returns>
        private static Dictionary<string, string> PrepareFileSystementities(IEnumerable<string> sourceFileEntityPathList)
        {
            Dictionary<string, string> fileEntityDictionary = new Dictionary<string, string>();//文件字典
            string parentDirectoryPath = "";
            foreach (string fileEntityPath in sourceFileEntityPathList)
            {
                string path = fileEntityPath;
                //保证传入的文件夹也被压缩进文件
                if (path.EndsWith(@"\"))
                {
                    path = path.Remove(path.LastIndexOf(@"\"));
                }

                parentDirectoryPath = Path.GetDirectoryName(path) + @"\";

                if (parentDirectoryPath.EndsWith(@":\\"))//防止根目录下把盘符压入的错误
                {
                    parentDirectoryPath = parentDirectoryPath.Replace(@"\\", @"\");
                }

                //获取目录中所有的文件系统对象
                Dictionary<string, string> subDictionary = GetAllFileSystemEntities(path, parentDirectoryPath);

                //将文件系统对象添加到总的文件字典中
                foreach (string key in subDictionary.Keys)
                {
                    if (!fileEntityDictionary.ContainsKey(key))//检测重复项
                    {
                        fileEntityDictionary.Add(key, subDictionary[key]);
                    }
                }
            }
            return fileEntityDictionary;
        }

        /// <summary>
        /// 压缩单个文件/文件夹
        /// </summary>
        /// <param name="sourceList">源文件/文件夹路径列表</param>
        /// <param name="zipFilePath">压缩文件路径</param>
        /// <param name="comment">注释信息</param>
        /// <param name="password">压缩密码</param>
        /// <param name="compressionLevel">压缩等级，范围从0到9，可选，默认为6</param>
        /// <returns></returns>
        public static bool CompressFile(string path, string zipFilePath,
            string comment = null, string password = null, int compressionLevel = 6)
        {
            return CompressFile(new string[] { path }, zipFilePath, comment, password, compressionLevel);
        }

        /// <summary>
        /// 压缩多个文件/文件夹
        /// </summary>
        /// <param name="sourceList">源文件/文件夹路径列表</param>
        /// <param name="zipFilePath">压缩文件路径</param>
        /// <param name="comment">注释信息</param>
        /// <param name="password">压缩密码</param>
        /// <param name="compressionLevel">压缩等级，范围从0到9，可选，默认为6</param>
        /// <returns></returns>
        public static bool CompressFile(IEnumerable<string> sourceList, string zipFilePath,
             string comment = null, string password = null, int compressionLevel = 6)
        {
            bool result = false;

            try
            {
                //检测目标文件所属的文件夹是否存在，如果不存在则建立
                string zipFileDirectory = Path.GetDirectoryName(zipFilePath);
                if (!Directory.Exists(zipFileDirectory))
                {
                    Directory.CreateDirectory(zipFileDirectory);
                }

                Dictionary<string, string> dictionaryList = PrepareFileSystementities(sourceList);

                using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipFilePath)))
                {
                    zipStream.Password = password;//设置密码
                    zipStream.SetComment(comment);//添加注释
                    zipStream.SetLevel(CheckCompressionLevel(compressionLevel));//设置压缩等级

                    foreach (string key in dictionaryList.Keys)//从字典取文件添加到压缩文件
                    {
                        if (File.Exists(key))//判断是文件还是文件夹
                        {
                            FileInfo fileItem = new FileInfo(key);

                            using (FileStream readStream = fileItem.Open(FileMode.Open,
                                FileAccess.Read, FileShare.Read))
                            {
                                ZipEntry zipEntry = new ZipEntry(dictionaryList[key]);
                                zipEntry.DateTime = fileItem.LastWriteTime;
                                zipEntry.Size = readStream.Length;
                                zipStream.PutNextEntry(zipEntry);
                                int readLength = 0;
                                byte[] buffer = new byte[BufferSize];

                                do
                                {
                                    readLength = readStream.Read(buffer, 0, BufferSize);
                                    zipStream.Write(buffer, 0, readLength);
                                } while (readLength == BufferSize);

                                readStream.Close();
                            }
                        }
                        else//对文件夹的处理
                        {
                            ZipEntry zipEntry = new ZipEntry(dictionaryList[key] + "/");
                            zipStream.PutNextEntry(zipEntry);
                        }
                    }

                    zipStream.Flush();
                    zipStream.Finish();
                    zipStream.Close();
                }

                result = true;
            }
            catch (System.Exception ex)
            {
                throw new Exception("压缩文件失败", ex);
            }

            return result;
        }
        /// <summary>
        /// 创建临时文件夹
        /// </summary>
        /// <param name="srcPath"></param>
        /// <param name="destPath"></param>
        public static void CopyDirectory(string srcPath, string destPath)
        {
            try
            {
                DirectoryInfo dir = new DirectoryInfo(srcPath);
                FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();  //获取目录下（不包含子目录）的文件和子目录
                foreach (FileSystemInfo i in fileinfo)
                {
                    if (i is DirectoryInfo)     //判断是否文件夹
                    {
                        if (!Directory.Exists(destPath + "\\" + i.Name))
                        {
                            Directory.CreateDirectory(destPath + "\\" + i.Name);   //目标目录下不存在此文件夹即创建子文件夹
                        }
                        CopyDirectory(i.FullName, destPath + "\\" + i.Name);    //递归调用复制子文件夹
                    }
                    else
                    {
                        File.Copy(i.FullName, destPath + "\\" + i.Name, true);      //不是文件夹即复制文件，true表示可以覆盖同名文件
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }

        /// <summary>
        /// 读取excel数据
        /// </summary>
        /// <param name="Path"></param>
        /// <returns></returns>
       
        public static void ExcelToDS(string Path)
        {
            try
            {
                Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();
                workbook.Open(Path);
                Aspose.Cells.Cells cells = workbook.Worksheets[0].Cells;

                for (int j = 1; j < cells.MaxDataRow + 1; j++)
                {
                    string id = cells[j, 0].StringValue;
                    string djdate = cells[j, 1].StringValue;
                    string type = cells[j, 2].StringValue;
                    int stauts = 2;
                    string name = cells[j, 4].StringValue;
                    string cardno = cells[j, 5].StringValue;
                    string sex = cells[j, 6].StringValue;
                    string date = cells[j, 7].StringValue;
                    string addr = cells[j, 8].StringValue;
                    string dep = cells[j, 9].StringValue;
                    string yxq = cells[j, 10].StringValue;
                    string uname = cells[j, 11].StringValue;
                    int i01 = 0;
                    string v02 = cells[j, 13].StringValue;
                    string v01 = cells[j, 14].StringValue;
                    string pname = cells[j, 15].StringValue;
                    string pono= cells[j, 16].StringValue;
                    string posex = cells[j, 17].StringValue;
                    string podate = cells[j, 18].StringValue;
                    string faname = cells[j, 19].StringValue;
                    string fano = cells[j, 20].StringValue;
                    string moname = cells[j, 21].StringValue;
                    string mono = cells[j, 22].StringValue;
                    string sonsex = cells[j, 23].StringValue;
                    string sondate = cells[j, 24].StringValue;
                    string sonname = cells[j, 25].StringValue;
                    string sono = cells[j, 26].StringValue;
                    string sql = string.Format(@"insert into T_CARDINFO(C_ID ,C_DJDATE ,C_TYPENAME,C_STAUTS,C_NAME,C_CARDNO,C_SEX,C_DATE,C_HJADDR,C_DEPARTMENT,C_YXDATE,C_UNAME,C_I01,C_V02,C_V01,C_PONAME,C_PONO,C_POSEX,C_PODATE,C_FANAME,C_FANO,C_MONAME,C_MONO,C_SONSEX,C_SONDATE,C_SONNAME,C_SONNO)  values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}','{17}','{18}','{19}','{20}','{21}','{22}','{23}','{24}','{25}','{26}')",
                        id, djdate, type, stauts, name, cardno, sex, date, addr, dep, yxq, uname, i01,v02, v01,pname,pono,posex,podate,faname,fano,moname,mono,sonsex,sondate,sonname,sono);
                    try
                    {
                        string connning = "data source =.; initial catalog = SgAutoArchiveSp; persist security info = True; user id = sa; password = 123456; Integrated Security=True";

                       /// string connning = System.Configuration.ConfigurationSettings.AppSettings["connectionStrings"];
                        SqlConnection con = new SqlConnection(connning);
                        con.Open();
                        //SgAutoArchiveSpEntities con = new SgAutoArchiveSpEntities();
                        SqlCommand cmd = new SqlCommand(sql, con);
                        cmd.ExecuteNonQuery();
                        con.Close();
                    }
                    catch (Exception ex)
                    {
                        //FileStream fs = new FileStream("E:\\log.txt", FileMode.OpenOrCreate);
                        // StreamWriter sw = new StreamWriter(Application.StartupPath + "\\log.txt", true, Encoding.GetEncoding("gbk"));
                        // sw.WriteLine(str + ":" + sql);
                        // sw.Close();
                    }

                }
            }
            catch (Exception ex)
            { }
            } 
        /// <summary>
        /// ds的导入excel
        /// </summary>
        /// <param name="Path"></param>
        /// <param name="oldds"></param>
        public static void DSToExcel(string Path, DataSet oldds)
        {
            //先得到汇总EXCEL的DataSet 主要目的是获得EXCEL在DataSet中的结构 
            string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source =" + Path + ";Extended Properties=Excel 8.0";
            OleDbConnection myConn = new OleDbConnection(strCon);
            string strCom = "select * from [Sheet$]";
            myConn.Open();
            OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, myConn);
            OleDbCommandBuilder builder = new OleDbCommandBuilder(myCommand);
            //QuotePrefix和QuoteSuffix主要是对builder生成InsertComment命令时使用。 
            builder.QuotePrefix = "[";     //获取insert语句中保留字符（起始位置） 
            builder.QuoteSuffix = "]"; //获取insert语句中保留字符（结束位置） 
            DataSet newds = new DataSet();
            myCommand.Fill(newds, "Table1");
            for (int i = 0; i < oldds.Tables[0].Rows.Count; i++)
            {
                //在这里不能使用ImportRow方法将一行导入到news中，因为ImportRow将保留原来DataRow的所有设置(DataRowState状态不变)。
               // 在使用ImportRow后newds内有值，但不能更新到Excel中因为所有导入行的DataRowState != Added
            DataRow nrow = newds.Tables["Table1"].NewRow();
                for (int j = 0; j < newds.Tables[0].Columns.Count; j++)
                {
                    nrow[j] = oldds.Tables[0].Rows[i][j];
                }
                newds.Tables["Table1"].Rows.Add(nrow);
            }
            myCommand.Update(newds, "Table1");
            myConn.Close();
        }
        /// <summary>
        /// 解压文件到指定文件夹
        /// </summary>
        /// <param name="sourceFile">压缩文件</param>
        /// <param name="destinationDirectory">目标文件夹，如果为空则解压到当前文件夹下</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public static bool DecomparessFile(string sourceFile, string destinationDirectory = null, string password = null)
        {
            try {
                bool result = false;

                if (!File.Exists(sourceFile))
                {
                    throw new FileNotFoundException("要解压的文件不存在", sourceFile);

                }

                if (string.IsNullOrWhiteSpace(destinationDirectory))
                {
                    destinationDirectory = Path.GetDirectoryName(sourceFile);
                }

                try
                {
                    if (!Directory.Exists(destinationDirectory))
                    {
                        Directory.CreateDirectory(destinationDirectory);
                    }

                    using (ZipInputStream zipStream = new ZipInputStream(File.Open(sourceFile, FileMode.Open,
                        FileAccess.Read, FileShare.Read)))
                    {
                        zipStream.Password = password;
                        ZipEntry zipEntry = zipStream.GetNextEntry();

                        while (zipEntry != null)
                        {
                            if (zipEntry.IsDirectory)//如果是文件夹则创建
                            {
                                Directory.CreateDirectory(Path.Combine(destinationDirectory,
                                    Path.GetDirectoryName(zipEntry.Name)));
                                oldstr = zipEntry.Name;
                            }
                            else
                            {
                                string fileName = Path.GetFileName(zipEntry.Name);
                                if (!string.IsNullOrEmpty(fileName) && fileName.Trim().Length > 0)
                                {
                                    FileInfo fileItem = new FileInfo(Path.Combine(destinationDirectory, zipEntry.Name));
                                    using (FileStream writeStream = fileItem.Create())
                                    {
                                        byte[] buffer = new byte[BufferSize];
                                        int readLength = 0;

                                        do
                                        {
                                            readLength = zipStream.Read(buffer, 0, BufferSize);
                                            writeStream.Write(buffer, 0, readLength);
                                        } while (readLength == BufferSize);

                                        writeStream.Flush();
                                        writeStream.Close();
                                    }
                                    fileItem.LastWriteTime = zipEntry.DateTime;
                                }
                            }

                            zipEntry = zipStream.GetNextEntry();//获取下一个文件

                        }

                        CopyDirectory(Program._jyfilePath + "\\" + oldstr, Program._lsfilePath);
                        ExcelToDS(Program._lsfilePath + "\\导出数据表.xls");
                        //DSToExcel((Program._jyfilePath + "\\" + oldstr, DataSet oldds);
                        //Workbook workbook = new Workbook();
                        //workbook.LoadFromFile(Program._lsfilePath+"\\"+"导出数据表.xls");
                        //workbook.SaveAsXml(Program._lsfilePath + "\\"+"表格数据.xml");
                        zipStream.Close();

                    }
                    // CopyDirectory(zipEntry.Name, Program._lsfilePath);

                    result = true;


                }
                catch (System.Exception ex)
                {
                    throw new Exception("文件解压发生错误", ex);
                }

                return result;
            }
            catch (Exception  ex) { return false; }
}
        #endregion


    }
}
